 /*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /**
 * Project  : EasyAvatar-Lib
 * Package  : net.solosky.easyavatar.api.impl
 * File     : QQWeiboFriendProvider.java
 * Author   : solosky < solosky772@qq.com >
 * Created  : 2011-10-25
 * License  : Apache License 2.0 
 */
package net.solosky.easyavatar.api.impl;

import java.io.IOException;

import net.solosky.easyavatar.api.ApiException;
import net.solosky.easyavatar.api.Avatar;
import net.solosky.easyavatar.api.Avatar.Scale;
import net.solosky.easyavatar.api.ErrorCode;
import net.solosky.easyavatar.api.Friend;
import net.solosky.easyavatar.api.FriendList;
import net.solosky.easyavatar.api.http.HttpClient;
import net.solosky.easyavatar.api.http.HttpRequest;
import net.solosky.easyavatar.api.http.HttpResponse;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.QqWeiboApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.SignatureType;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;

/**
 *
 * QQ微博好友提供实现，好友列表为我跟随的人
 *
 * @author solosky <solosky772@qq.com>
 *
 */
public class QWeiboFriendProvider extends AbstractOAuthFriendProvider {
	private static final String URL_SELFINFO = "http://open.t.qq.com/api/user/info";
	private static final String URL_MYFRIENDS = "http://open.t.qq.com/api/friends/idollist";		//我主动Follow的人认为是朋友关系
	private static final String URL_MAYKNOWNS = "http://open.t.qq.com/api/other/kownperson";

	@Override
	public void init() throws ApiException, IOException {
	}

	@Override
	public FriendList retireMyFriends(String index) throws ApiException, IOException {
		index = index!=null ? index : "0";
		OAuthRequest req = createOAuthRequest(Verb.GET, URL_MYFRIENDS);
		req.addQuerystringParameter("format", "json");
		req.addQuerystringParameter("reqnum", ""+20);
		req.addQuerystringParameter("startindex", index);
		Response res = executeAuthRequest(req);
		try {
			JSONObject data = validateResponse(res).getJSONObject("data");
			FriendList friendList = new FriendList();
			friendList.setHasNext(data.getInt("hasnext")==1);
			friendList.setNextIndex((Integer.parseInt(index)+1)+"");
			friendList.setHasGroup(false);
			JSONArray entries = data.getJSONArray("info");
			for(int i=0; i<entries.length(); i++){
				JSONObject entry = entries.getJSONObject(i);
				Friend friend = new Friend();
				friend.setFid(entry.optString("name"));
				friend.setNick(entry.optString("name"));	//这里需要反着来，因为nick是中文，而name是英文...
				friend.setName(entry.optString("nick"));
				friend.getAvatar().setUrl(entry.optString("head"));
				friendList.getFriends().add(friend);
			}
			return friendList;
		} catch (JSONException e) {
			throw new ApiException(ErrorCode.INVALID_RESPONSE, e);
		}
	}

	@Override
	public FriendList retireMayKnowns(String index) throws ApiException,
			IOException {
		OAuthRequest req = createOAuthRequest(Verb.GET, URL_MAYKNOWNS);
		req.addQuerystringParameter("format", "json");
		Response res = executeAuthRequest(req);
		try {
			JSONArray entries =validateResponse(res).getJSONArray("data");
			FriendList friendList = new FriendList();
			friendList.setHasNext(true);	//这个接口总是有数据返回
			friendList.setNextIndex(null);	//Index参数无关
			friendList.setHasGroup(false);
			for(int i=0; i<entries.length(); i++){
				JSONObject entry = entries.getJSONObject(i);
				Friend friend = new Friend();
				friend.setFid(entry.optString("id"));
				friend.setNick(entry.optString("name"));
				friend.setName(entry.optString("nick"));
				friend.getAvatar().setUrl(entry.optString("head"));
				friendList.getFriends().add(friend);
			}
			return friendList;
		} catch (JSONException e) {
			throw new ApiException(ErrorCode.INVALID_RESPONSE, e);
		}
	}

	@Override
	public Avatar retireFriendAvatar(Friend friend, Scale scale)
			throws ApiException, IOException {
		if(friend.getAvatar().getUrl()==null)	
			throw new ApiException(ErrorCode.NO_AVATAR);
		HttpClient client = new HttpClient();
		HttpRequest req = new HttpRequest(friend.getAvatar().getUrl()+"/"+(scale==Scale.LARGE?"100":"40"), "GET");
		HttpResponse res = client.execute(req);
		if(res.getResponseCode()==HttpResponse.HTTP_OK){
			friend.getAvatar().setData(res.getResponseData());
			return friend.getAvatar();
		}else{
			throw new ApiException(ErrorCode.INVALID_RESPONSE);
		}
	}

	@Override
	public Avatar retireMyAvatar(Friend friend, Scale scale) throws ApiException,
			IOException {
		return retireFriendAvatar(friend, scale);
	}

	@Override
	public Friend retireMyInfo() throws ApiException, IOException {
		OAuthRequest req = createOAuthRequest(Verb.GET, URL_SELFINFO);
		req.addQuerystringParameter("format", "json");
		Response res = executeAuthRequest(req);
		try {
			JSONObject data = validateResponse(res).getJSONObject("data");
			Friend my = new Friend();
			my.setName(data.optString("name"));
			my.setNick(data.optString("nick"));
			my.getAvatar().setUrl(data.optString("head"));
			return my;
		} catch (JSONException e) {
			throw new ApiException(ErrorCode.INVALID_RESPONSE, e);
		}
	}
	
	@Override
	protected OAuthService doCreateOAuthService(
			String appKey, String appSecret, String callback) {
		OAuthService service = new ServiceBuilder()
		.provider(QqWeiboApi.class)
		.apiKey(appKey).apiSecret(appSecret)
		.signatureType(SignatureType.QueryString)
		.callback(callback) // it's important, use default way(pass oob) would be wrong
		.build();
		return service;
	}

	private JSONObject validateResponse(Response res) throws ApiException, JSONException{
		JSONObject json = new JSONObject(res.getBody());
		if (json.getInt("ret")!=0){
			throw new ApiException(ErrorCode.INVALID_RESPONSE);	//细化异常。。
		}else{
			return json;
		}
	}

}
